{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Iteratorパターン\n",
    "\n",
    "* Iteratorパターンとは\n",
    "    * 何かがたくさん集まっているときに、それを順番に指し示していき全体をスキャンしていく処理を行うためのもの\n",
    "    * iterate\n",
    "        * 何かを繰り返すという意味の単語\n",
    "        * 日本語では反復子と呼ばれることがある\n",
    "        * 種類\n",
    "            * 順方向に一度だけスキャンする (オーソドックス)\n",
    "            * 最後尾から開始して逆方向に進む\n",
    "            * 順方向にも逆方向にも進む (nextメソッドだけではなくpreviousメソッドも持つ)\n",
    "            * 番号を指定していきなり底にジャンプする\n",
    "        * deleteIteratorは不要\n",
    "            * 言語によっては自動的にインスタンスが削除されないがJavaは削除されるので不要\n",
    "    * 数え上げの仕組みがAggregate役の外に置かれている\n",
    "        * 1つのConcreteAggregate役に対して複数のConcreteIterator役を作ることができる"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Aggregateインタフェース\n",
    "\n",
    "* Aggregateインタフェース\n",
    "    * 数え上げを行うものの<font color=\"red\">集合体</font>を表す\n",
    "    * このインタフェースを実装しているクラスは、配列のように<font color=\"red\">何かがたくさん集まっているも</font>のになる\n",
    "    * aggregate\n",
    "        * 集める、集まる、集合という意味の英単語\n",
    "    * 宣言されているメソッド\n",
    "        * iteratorメソッド\n",
    "            * 集合に対応するIteratorを1個作成するためのもの\n",
    "            * 使う状況\n",
    "                * 集合体を数え上げたい\n",
    "                * 集合体をスキャンしたい\n",
    "                * 集合体を1つずつ調べていきたい\n",
    "            * このメソッドを使ってIteratorインタフェースを実装したクラスのインスタンスを1個作る"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "### 変数の設定\n",
    "name=Aggregate\n",
    "\n",
    "### ソースの編集\n",
    "cat <<- EOS > ${name}.java\n",
    "public interface ${name} {\n",
    "    public abstract Iterator iterator();\n",
    "}\n",
    "EOS\n",
    "\n",
    "### コンパイル\n",
    "javac ${name}.java\n",
    "#javac -encoding UTF-8 ${name}.java"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Iteratorインタフェース\n",
    "\n",
    "* Iteratorインタフェース\n",
    "    * <font color=\"red\">要素の数え上げ</font>を行うもの\n",
    "        * ループ変数のような役割を果たすもの\n",
    "    * 宣言されているメソッド\n",
    "        * hasNextメソッド\n",
    "            * 次の要素が存在するかどうかを調べる\n",
    "                * <font color=\"red\">次にnextメソッドを呼んでも大丈夫かどうかを調べる</font>\n",
    "            * ループの終了条件で使うためのもの\n",
    "            * 戻り値はboolean型\n",
    "                * 有ればtrue、無ければfalse\n",
    "        * nextメソッド\n",
    "            * 次の要素を得る\n",
    "                * 戻り値はObject型\n",
    "                    * 集合体の要素を一個返す\n",
    "            * 次の要素を返すように内部状態を次に進めておくという隠れ仕事もある\n",
    "                * 隠れ仕事はIteratorインタフェースを実装しているクラスの方に具体的な動きが記載されている\n",
    "                    * ここではBookShelfIteratorクラス\n",
    "            * <font color=\"red\">現在の要素を返しつつ次の位置に進める</font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "### 変数の設定\n",
    "name=Iterator\n",
    "\n",
    "### ソースの編集\n",
    "cat <<- EOS > ${name}.java\n",
    "public interface ${name} {\n",
    "    public abstract boolean hasNext();\n",
    "    public abstract Object next();\n",
    "}\n",
    "EOS\n",
    "\n",
    "### コンパイル\n",
    "#javac ${name}.java\n",
    "javac -encoding UTF-8 ${name}.java"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Bookクラス\n",
    "\n",
    "* 本を表すクラス\n",
    "    * 宣言されているメソッド\n",
    "        * getNameメソッド\n",
    "            * 本の名前を得る\n",
    "            * 本の名前はコンストラクタでインスタンスを初期化するときに引数で指定する"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "### 変数の設定\n",
    "name=Book\n",
    "\n",
    "### ソースの編集\n",
    "cat <<- EOS > ${name}.java\n",
    "public class ${name} {\n",
    "    private String name;\n",
    "    public Book(String name) {\n",
    "        this.name = name;\n",
    "    }\n",
    "    public String getName() {\n",
    "        return name;\n",
    "    }\n",
    "}\n",
    "EOS\n",
    "\n",
    "### コンパイル\n",
    "#javac ${name}.java\n",
    "javac -encoding UTF-8 ${name}.java"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## BookShelfクラス\n",
    "\n",
    "* 本棚を表しているクラス\n",
    "    * Aggregateインタフェースを実装している\n",
    "        * 「implements Aggregate」がAggregateインタフェースを実装していることを表現している\n",
    "        * Aggregateインタフェースで宣言されていたiteratorメソッドの実態が書かれている"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "### 変数の設定\n",
    "name=BookShelf\n",
    "\n",
    "### ソースの編集\n",
    "cat <<- EOS > ${name}.java\n",
    "public class ${name} implements Aggregate {\n",
    "    //# Bookの配列を持つbooksフィールド。privateにして外から不用意に変更されることを防ぐ\n",
    "    private Book[] books;\n",
    "    private int last = 0;\n",
    "    \n",
    "    public BookShelf(int maxsize) {\n",
    "    　　　　//# maxsizeは配列の大きさで、最初にBookShelfのインスタンスを作るときに指定する\n",
    "        this.books = new Book[maxsize];\n",
    "    }\n",
    "    \n",
    "    public Book getBookAt(int index) {\n",
    "        return books[index];\n",
    "    }\n",
    "    \n",
    "    public void appendBook(Book book) {\n",
    "        this.books[last] = book;\n",
    "        last++;\n",
    "    }\n",
    "    \n",
    "    public int getLength() {\n",
    "        return last;\n",
    "    }\n",
    "    \n",
    "    //# BookShelfクラスに対応するIteratorとしてBookShelfIteratorというクラスのインスタンスを生成してそれを返すメソッド\n",
    "    //# 本棚の本を数えたいときに呼び出す\n",
    "    public Iterator iterator() {\n",
    "        return new BookShelfIterator(this);\n",
    "    }\n",
    "}\n",
    "EOS\n",
    "\n",
    "### コンパイル\n",
    "#javac ${name}.java\n",
    "javac -encoding UTF-8 ${name}.java"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## BookShelfIteratorクラス\n",
    "\n",
    "* BookShelfクラスのスキャンを行うクラス\n",
    "    * Iteratorインタフェースを実装している\n",
    "        * BookShelfIteratorをIteratorとして扱うため"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "### 変数の設定\n",
    "name=BookShelfIterator\n",
    "\n",
    "### ソースの編集\n",
    "cat <<- EOS > ${name}.java\n",
    "public class ${name} implements Iterator {\n",
    "    //# BookShelfIteratorがスキャンする本棚に相当するbookshelfフィールド\n",
    "    private BookShelf bookShelf;\n",
    "    //# 現在注目している本を指す添字に相当するindexフィールド\n",
    "    private int index;\n",
    "    \n",
    "    //# 渡されたBookShelfインスタンスをbookShelfフィールドに保存し、indexを0にしているコンストラクタ\n",
    "    public BookShelfIterator(BookShelf bookShelf) {\n",
    "        this.bookShelf = bookShelf;\n",
    "        this.index = 0;\n",
    "    }\n",
    "    \n",
    "    //# Iteratorインタフェースで宣言されているメソッドを実装したhasNextメソッド\n",
    "    //# indexが本棚の本の冊数より小さいかどうかで判断している\n",
    "    public boolean hasNext() {\n",
    "        if (index < bookShelf.getLength()) {\n",
    "            return true;\n",
    "        } else {\n",
    "            return false;\n",
    "        }\n",
    "    }\n",
    "    \n",
    "    //# Iteratorインタフェースで宣言されているメソッドを実装したnextメソッド\n",
    "    //# 現在注目している本(Bookのインスタンス)を返し、更に次に進める\n",
    "    public Object next() {\n",
    "        //# 戻り値として返すべき本をbookという変数にとっておく\n",
    "        Book book = bookShelf.getBookAt(index);\n",
    "        //# indexを次に進める\n",
    "        index++;\n",
    "        return book;\n",
    "    }\n",
    "}\n",
    "EOS\n",
    "\n",
    "### コンパイル\n",
    "#javac ${name}.java\n",
    "javac -encoding UTF-8 ${name}.java"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Mainクラス"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Around the World in 80 Days\n",
      "Bible\n",
      "Cinderella\n",
      "Daddy-Long-Legs\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "### 変数の設定\n",
    "name=Main\n",
    "\n",
    "### ソースの編集\n",
    "cat <<- EOS > ${name}.java\n",
    "public class ${name} {\n",
    "    public static void main(String[] args) {\n",
    "        //# 本が4冊入る本棚を作る\n",
    "        BookShelf bookShelf = new BookShelf(4);\n",
    "        \n",
    "        //# 4冊の本を作って入れる\n",
    "        bookShelf.appendBook(new Book(\"Around the World in 80 Days\"));\n",
    "        bookShelf.appendBook(new Book(\"Bible\"));\n",
    "        bookShelf.appendBook(new Book(\"Cinderella\"));\n",
    "        bookShelf.appendBook(new Book(\"Daddy-Long-Legs\"));\n",
    "        \n",
    "        //# 本棚をスキャンするためのIteratorのインスタンスitを生成\n",
    "        Iterator it = bookShelf.iterator();\n",
    "        \n",
    "        //# 本がある限りwhileループが回る\n",
    "        while (it.hasNext()) {\n",
    "            //# 本を1冊1冊調べる\n",
    "            Book book = (Book) it.next();\n",
    "            System.out.println(book.getName());\n",
    "        }\n",
    "    }\n",
    "}\n",
    "EOS\n",
    "\n",
    "### コンパイル\n",
    "#javac ${name}.java\n",
    "javac -encoding UTF-8 ${name}.java\n",
    "\n",
    "### 実行\n",
    "#java -classpath ${classpath} ${name}\n",
    "java ${name}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "\n",
    "current_dir=`pwd`\n",
    "isbn=\"ISBN4-7973-2703-0\"\n",
    "fig=\"Fig.1-2\"\n",
    "\n",
    "### サンプルコードの作成\n",
    "cat <<- EOS > ${current_dir}/plantuml/${isbn}_${fig}.pu\n",
    "@startuml\n",
    "skinparam classAttributeIconSize 0\n",
    "\n",
    "interface Aggregate {\n",
    "    {abstract} +iterator()\n",
    "}\n",
    "\n",
    "interface Iterator {\n",
    "    {abstract} +hasNext()\n",
    "    {abstract} +next()    \n",
    "}\n",
    "\n",
    "class Book {\n",
    "    -name : String\n",
    "    +getName()\n",
    "}\n",
    "\n",
    "class BookShelf {\n",
    "    -books : Book[]\n",
    "    -last : int\n",
    "    +getBookAt()\n",
    "    +appendBook()\n",
    "    +getLength()\n",
    "    +iterator()\n",
    "}\n",
    "\n",
    "class BookShelfIterator {\n",
    "    -bookShelf : BookShelf\n",
    "    -index : int\n",
    "    +hasNext()\n",
    "    +next()\n",
    "}\n",
    "\n",
    "\n",
    "Aggregate --> Iterator : Creates >\n",
    "Aggregate <|.. BookShelf\n",
    "Iterator <|.. BookShelfIterator\n",
    "BookShelf <--o BookShelfIterator\n",
    "Book <--o BookShelf\n",
    "\n",
    "@enduml\n",
    "EOS\n",
    "\n",
    "### サンプルコードからUMLの図を作成\n",
    "java -jar plantuml.jar -o ${current_dir}/img -tpng ${current_dir}/plantuml/${isbn}_${fig}.pu"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "<img src=\"img/ISBN4-7973-2703-0_Fig.1-2.png\" alt=\"サンプルプログラムのクラス図\" title=\"サンプルプログラムのクラス図\" align=\"left\" />  \n",
    "<br clear=\"left\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "* Bookクラス\n",
    "    * getNameメソッドで本の名前を得る\n",
    "    * 本の名前はコンストラクタでインスタンス生成時に引数で指定する\n",
    "* Iteratorインタフェース\n",
    "    * 要素の数え上げをするためのメソッドを宣言している\n",
    "        * 次の要素が存在するか調べるhasNextメソッド\n",
    "        * 次の要素を得るためのnextメソッド\n",
    "* BookShelfIteratorクラス\n",
    "    * Iteratorインタフェースを実装しているクラス\n",
    "        * hasNext, nextメソッドの実体がある\n",
    "* Aggregateインタフェース\n",
    "    * Iteratorを生成するメソッドが宣言されている\n",
    "        * 集合体に対応するIteratorを1個生成するためのiteratorメソッド\n",
    "* BookShelfクラス\n",
    "    * Aggregateインタフェースを実装しているクラス\n",
    "        * Aggregateインタフェースで宣言されていた<font color=\"red\">iteratorメソッドの実体</font>がある\n",
    "            * BookShelfクラスに対応するIteratorとしてBookShelfIteratorというクラスのインスタンスを生成して返す\n",
    "    * Bookの配列を持つ\n",
    "        * BookShelfクラスのインスタンスはBookクラスのインスタンスを複数持つ"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "%%bash\n",
    "\n",
    "current_dir=`pwd`\n",
    "isbn=\"ISBN4-7973-2703-0\"\n",
    "fig=\"Fig.1-4\"\n",
    "\n",
    "### サンプルコードの作成\n",
    "cat <<- EOS > ${current_dir}/plantuml/${isbn}_${fig}.pu\n",
    "@startuml\n",
    "skinparam classAttributeIconSize 0\n",
    "\n",
    "interface Aggregate {\n",
    "    {abstract} +iterator()\n",
    "}\n",
    "\n",
    "interface Iterator {\n",
    "    {abstract} +hasNext()\n",
    "    {abstract} +next()    \n",
    "}\n",
    "\n",
    "class ConcreteAggregate {\n",
    "    +iterator()\n",
    "}\n",
    "\n",
    "class ConcreteIterator {\n",
    "    -aggregate\n",
    "    +hasNext()\n",
    "    +next()\n",
    "}\n",
    "\n",
    "\n",
    "Aggregate --> Iterator : Creates >\n",
    "Aggregate <|.. ConcreteAggregate\n",
    "Iterator <|.. ConcreteIterator\n",
    "ConcreteAggregate <--o ConcreteIterator\n",
    "\n",
    "@enduml\n",
    "EOS\n",
    "\n",
    "### サンプルコードからUMLの図を作成\n",
    "java -jar plantuml.jar -o ${current_dir}/img -tpng ${current_dir}/plantuml/${isbn}_${fig}.pu"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## Iteratorパターンの登場人物\n",
    "\n",
    "<img src=\"img/ISBN4-7973-2703-0_Fig.1-4.png\" alt=\"Iteratorパターンのクラス図\" title=\"Iteratorパターンのクラス図\" align=\"left\" />  \n",
    "<br clear=\"left\">\n",
    "\n",
    "* Iterator(反復子)役\n",
    "    * 要素を順番にスキャンしていく<font color=\"red\">インタフェース(API)</font>を定める役\n",
    "        * サンプルプログラムではInterfaceインタフェースがこの役をつとめる\n",
    "            * hasNextメソッドとnextメソッドを定める\n",
    "* ConcreteIterator(具体的な反復子)役\n",
    "    * Iterator役が定めたインタフェース(API)を実際に実装する役\n",
    "        * サンプルプログラムではBookShelfIteratorクラスがこの役をつとめる\n",
    "    * スキャンするために必要な情報を持っている必要がある\n",
    "        * サンプルプログラム\n",
    "            * BookShelfクラスのインスタンスをbookShelfフィールドで覚えている\n",
    "            * 注目している本をindexフィールドで覚えている\n",
    "            * hasNextメソッドとnextメソッドを実装している\n",
    "* Aggregate(集合体)役\n",
    "    * Iterator役を作り出すインタフェース(API)を定める役\n",
    "        * サンプルプログラムではAggregateインタフェースがこの役をつとめる\n",
    "            * iteratorメソッドを定めている\n",
    "                * 「私が持っている要素を順番にスキャンしてくれる人」を作り出すメソッド\n",
    "* ConcreteAggregate(具体的な集合体)役\n",
    "    * Aggregate役が定めたインタフェース(API)を実際に実装する役\n",
    "        * サンプルプログラムではBookShelfクラスがこの役をつとめる\n",
    "            * iteratorメソッドを実装している\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Around the World in 80 Days\n",
      "Bible\n",
      "Cinderella\n",
      "Daddy-Long-Legs\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "# 以下練習問題用\n",
    "\n",
    "# =================== #\n",
    "name=Aggregate\n",
    "cat <<- EOS > ${name}.java\n",
    "\n",
    "public interface ${name} {\n",
    "    public abstract Iterator iterator();\n",
    "}\n",
    "\n",
    "EOS\n",
    "\n",
    "# =================== #\n",
    "name=Iterator\n",
    "cat <<- EOS > ${name}.java\n",
    "\n",
    "public interface ${name} {\n",
    "    public abstract boolean hasNext();\n",
    "    public abstract Object next();\n",
    "}\n",
    "\n",
    "EOS\n",
    "\n",
    "# =================== #\n",
    "name=Book\n",
    "cat <<- EOS > ${name}.java\n",
    "\n",
    "public class ${name} {\n",
    "    private String name;\n",
    "    public Book(String name) {\n",
    "        this.name = name;\n",
    "    }\n",
    "    public String getName() {\n",
    "        return name;\n",
    "    }\n",
    "}\n",
    "\n",
    "EOS\n",
    "\n",
    "# =================== #\n",
    "name=BookShelf\n",
    "cat <<- EOS > ${name}.java\n",
    "\n",
    "public class ${name} implements Aggregate {\n",
    "    private Book[] books;\n",
    "    private int last = 0;\n",
    "    \n",
    "    public BookShelf(int maxsize) {\n",
    "        this.books = new Book[maxsize];\n",
    "    }\n",
    "    \n",
    "    public Book getBookAt(int index) {\n",
    "        return books[index];\n",
    "    }\n",
    "    \n",
    "    public void appendBook(Book book) {\n",
    "        this.books[last] = book;\n",
    "        last++;\n",
    "    }\n",
    "    \n",
    "    public int getLength() {\n",
    "        return last;\n",
    "    }\n",
    "    \n",
    "    public Iterator iterator() {\n",
    "        return new BookShelfIterator(this);\n",
    "    }\n",
    "}\n",
    "\n",
    "EOS\n",
    "\n",
    "# =================== #\n",
    "name=BookShelfIterator\n",
    "cat <<- EOS > ${name}.java\n",
    "\n",
    "public class ${name} implements Iterator {\n",
    "    private BookShelf bookShelf;\n",
    "    private int index;\n",
    "    \n",
    "    public BookShelfIterator(BookShelf bookShelf) {\n",
    "        this.bookShelf = bookShelf;\n",
    "        this.index = 0;\n",
    "    }\n",
    "    \n",
    "    public boolean hasNext() {\n",
    "        if (index < bookShelf.getLength()) {\n",
    "            return true;\n",
    "        } else {\n",
    "            return false;\n",
    "        }\n",
    "    }\n",
    "    \n",
    "    public Object next() {\n",
    "        Book book = bookShelf.getBookAt(index);\n",
    "        index++;\n",
    "        return book;\n",
    "    }\n",
    "}\n",
    "\n",
    "EOS\n",
    "\n",
    "# =================== #\n",
    "name=Main\n",
    "cat <<- EOS > ${name}.java\n",
    "\n",
    "public class ${name} {\n",
    "    public static void main(String[] args) {\n",
    "        BookShelf bookShelf = new BookShelf(4);\n",
    "        \n",
    "        bookShelf.appendBook(new Book(\"Around the World in 80 Days\"));\n",
    "        bookShelf.appendBook(new Book(\"Bible\"));\n",
    "        bookShelf.appendBook(new Book(\"Cinderella\"));\n",
    "        bookShelf.appendBook(new Book(\"Daddy-Long-Legs\"));\n",
    "        \n",
    "        //# Iterator型の変数にbookShelf.iteratorの返り値を代入している(BookShelfIterator型ではない)\n",
    "        //# あくまでIteratorのメソッドを使ってプログラミング行おうという姿勢を示している\n",
    "        Iterator it = bookShelf.iterator();\n",
    "        \n",
    "        while (it.hasNext()) {\n",
    "            Book book = (Book) it.next();\n",
    "            System.out.println(book.getName());\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "EOS\n",
    "\n",
    "### コンパイル\n",
    "#javac ${name}.java\n",
    "javac -encoding UTF-8 ${name}.java\n",
    "\n",
    "### 実行\n",
    "#java -classpath ${classpath} ${name}\n",
    "java ${name}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
